﻿using Baidu.Aip.Ocr;
using MediaInfoDotNet;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SimpleConnection_UDP_WIN.utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using System.Windows.Forms;
using VideoMergeSplitApp.data;
using VideoMergeSplitApp.ui.dialog;
using VideoMergeSplitApp.utils;
using Vlc.DotNet.Forms;
using WindowsImageCompressionApp.utils;
using static System.Net.Mime.MediaTypeNames;

namespace VideoMergeSplitApp.ui
{
    public partial class BatchSplittingForm : Form
    {

        string videoPath = "";


        public BatchSplittingForm(string videoPath)
        {
            InitializeComponent();
            this.videoPath = videoPath;
        }


        private void BatchSplittingForm_Load(object sender, EventArgs e)
        {
            label1.Text = videoPath;

            vlcControl1.Play(new FileInfo(videoPath));

            taskList = new List<TaskBean>();

            MediaFile mediaFile = new MediaFile(videoPath);
            TimeSpan total = TimeSpan.FromMilliseconds(mediaFile.Video[0].duration); // 将毫秒转换为TimeSpan对象

            videoTotalTimeStr = $"{total.Hours}:{total.Minutes}:{total.Seconds}";
            videoTotalTime = mediaFile.Video[0].duration;

            trackBar1.Maximum = videoTotalTime;

            baidu_ocr_client = new Ocr(BaiduApi.BAIDU_OCR_apiKey, BaiduApi.BAIDU_OCR_secretKey);
            baidu_ocr_client.Timeout = 5000;


        }

        Ocr baidu_ocr_client;


        string videoTotalTimeStr;
        int videoTotalTime;


        List<TaskBean> taskList;

        long lastInTime, lastOutTime;
        string lastInTimeStr, lastOutTimeStr, lastNameStr;


        private void button2_Click(object sender, EventArgs e)
        {

            if (lastOutTime != 0 && vlcControl1.Time > lastOutTime)
            {
                MessageBox.Show("不能大于上一个出点");
                return;
            }


            //创建对象
            TimeSpan total = TimeSpan.FromMilliseconds(vlcControl1.Time); // 将毫秒转换为TimeSpan对象
                                                                          // 添加列表项
            lastInTime = vlcControl1.Time;
            lastInTimeStr = $"{total.Hours}:{total.Minutes}:{total.Seconds}";

            toolStripStatusLabel2.Text = $"当前对象切入点 {lastInTimeStr}";

            //控制按钮
            button2.Enabled = false;

            CheckAndAddToTheQueue();
        }

        string expName;

        private void button3_Click(object sender, EventArgs e)
        {

            if (vlcControl1.Time < lastInTime)
            {
                MessageBox.Show("不能小于上一个入点");
                return;
            }

            // 获取最后一个项
            TimeSpan total = TimeSpan.FromMilliseconds(vlcControl1.Time); // 将毫秒转换为TimeSpan对象

            lastOutTime = vlcControl1.Time;
            lastOutTimeStr = $"{total.Hours}:{total.Minutes}:{total.Seconds}";

            toolStripStatusLabel2.Text = $"当前对象切出点 {lastOutTimeStr}";

            //控制按钮
            button3.Enabled = false;

            CheckAndAddToTheQueue();
        }

        string openLastDir;

        int operationDuration = 0;

        private void button4_Click(object sender, EventArgs e)
        {
            //开始处理任务时，必须保证切入点已关闭，并队列中有任务
            if (listView1.Items.Count > 0 && taskList.Count > 0)
            {

                //禁用 开始任务按钮  以防二次点击
                button4.Enabled = false;

                operationDuration = 0;
                timer1.Start();


                // 在子线程中
                Task.Run(() =>
                    {

                        foreach (TaskBean task in taskList)
                        {
                            //在此 判断文件是否存在，跳出循环


                            //获取索引
                            int index = taskList.IndexOf(task);
                            string cmd = $" -i \"{videoPath}\" -ss {task.inTimeStr} -to {task.outTimeStr} -c copy \"{task.name}\"";
                            CmdUtil.RunFFCmd(cmd);
                            Console.WriteLine(cmd);

                            this.Invoke(new Action(() =>
                              {
                                  int progress = (int)Math.Round((float)(index + 1) / (float)taskList.Count * 100);
                                  toolStripProgressBar1.Value = progress;

                              }));
                        }

                        this.Invoke(new Action(() =>
                        {

                            Form1 form1 = new Form1();
                            if (form1.menuItem8.Checked)
                                SoundUtil.playReminderTone();

                            MessageBox.Show($"操作完成，请自行查看文件完整性，共导出 {taskList.Count} 个新文件", "提示");
                            timer1.Stop();

                            //解禁
                            button4.Enabled = true;

                            if (form1.menuItem2.Checked)
                            {
                                DBUtil.openExplorerDir(new FileInfo(openLastDir).DirectoryName);
                                form1.Dispose();
                            }

                            if (checkBox2.Checked)
                            {
                                clearList();
                            }

                        }));
                    });
            }
        }

        #region vlc寻找类库
        /// <summary>
        /// vlc寻找类库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void vlcControl1_VlcLibDirectoryNeeded_1(object sender, Vlc.DotNet.Forms.VlcLibDirectoryNeededEventArgs e)
        {
            var currentAssembly = Assembly.GetEntryAssembly();
            var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;
            if (currentDirectory == null)
                return;
            if (AssemblyName.GetAssemblyName(currentAssembly.Location).ProcessorArchitecture == ProcessorArchitecture.X86)
                e.VlcLibDirectory = new DirectoryInfo(Path.Combine(currentDirectory, @"libvlc\win-x86"));
            else
                e.VlcLibDirectory = new DirectoryInfo(Path.Combine(currentDirectory, @"libvlc\win-x64"));

            if (!e.VlcLibDirectory.Exists)
            {
                var folderBrowserDialog = new FolderBrowserDialog();
                folderBrowserDialog.Description = "请选择 Vlc 安装目录";
                folderBrowserDialog.RootFolder = Environment.SpecialFolder.CommonProgramFiles;
                folderBrowserDialog.ShowNewFolderButton = true;
                if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
                {
                    e.VlcLibDirectory = new DirectoryInfo(folderBrowserDialog.SelectedPath);
                }
            }
        }
        #endregion

        private void vlcControl1_TimeChanged(object sender, Vlc.DotNet.Core.VlcMediaPlayerTimeChangedEventArgs e)
        {
            if (showNewTime)
            {
                TimeSpan total = TimeSpan.FromMilliseconds(vlcControl1.Time); // 将毫秒转换为TimeSpan对象
                this.Invoke(new Action(() =>
               {
                   // 在这里更新UI控件的内容
                   label2.Text = $"{total.Hours}:{total.Minutes}:{total.Seconds} / {videoTotalTimeStr}";
                   trackBar1.Value = ((int)vlcControl1.Time);
               }));
            }
        }

        bool showNewTime = true;


        private void trackBar1_MouseDown(object sender, MouseEventArgs e)
        {
            showNewTime = false;

        }

        private void trackBar1_MouseUp(object sender, MouseEventArgs e)
        {
            showNewTime = true;
            vlcControl1.VlcMediaPlayer.Position = (float)trackBar1.Value / (float)trackBar1.Maximum;
        }


        private void setVlcPositionText(float d)
        {

            TimeSpan total = TimeSpan.FromMilliseconds(vlcControl1.Time); // 将毫秒转换为TimeSpan对象
            this.Invoke(new Action(() =>
            {
                // 在这里更新UI控件的内容
                label2.Text = $"{total.Hours}:{total.Minutes}:{total.Seconds} / {videoTotalTimeStr}";
                trackBar1.Value = ((int)vlcControl1.Time);
            }));

        }



        private void BatchSplittingForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            vlcControl1.Dispose();
        }



        #region 播放与暂停控制
        private void playAndPause()
        {
            if (vlcControl1.VlcMediaPlayer.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Playing)
            {
                vlcControl1.VlcMediaPlayer.Pause();
                label2.BackColor = Color.Orange;
            }
            else if (vlcControl1.VlcMediaPlayer.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Ended)
            {
                if (File.Exists(videoPath))
                {
                    vlcControl1.Play(new FileInfo(videoPath));
                    label2.BackColor = Color.LimeGreen;
                }
            }
            else
            {
                vlcControl1.VlcMediaPlayer.Play();
                label2.BackColor = Color.LimeGreen;
            }
        }
        #endregion



        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
        
            if (keyData == Keys.Space)
            {
                playAndPause();
                return true;
            }

            if ( keyData == (Keys.Left | Keys.Shift))
            {
                toolStripStatusLabel2.Text = "5倍快退中...";
                vlcControl1.VlcMediaPlayer.Position -= (float)5000 / (float)trackBar1.Maximum;
                setVlcPositionText(vlcControl1.VlcMediaPlayer.Position);
                return true;
            }
            if (keyData == (Keys.Right | Keys.Shift))
            {
                toolStripStatusLabel2.Text = "5倍快进中...";
                vlcControl1.VlcMediaPlayer.Position += (float)5000 / (float)trackBar1.Maximum;
                setVlcPositionText(vlcControl1.VlcMediaPlayer.Position);
                return true;
            }

            if (keyData == Keys.Right)
            {
                toolStripStatusLabel2.Text = "快进中...";
                vlcControl1.VlcMediaPlayer.Position += (float)1000 / (float)trackBar1.Maximum;
                setVlcPositionText(vlcControl1.VlcMediaPlayer.Position);
                return true;
            }
            if (keyData == Keys.Left)
            {
                toolStripStatusLabel2.Text = "快退中...";
                vlcControl1.VlcMediaPlayer.Position -= (float)1000 / (float)trackBar1.Maximum;
                setVlcPositionText(vlcControl1.VlcMediaPlayer.Position);
                return true;
            }

            // 对于其他键盘事件，使用默认的处理方式
            return base.ProcessCmdKey(ref msg, keyData);
        }




        private void button1_Click(object sender, EventArgs e)
        {
            clearList();
        }

        private void clearList()
        {
            taskList.Clear();
            listView1.Items.Clear();
        }

        /// <summary>
        /// 截图到图库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            capVlcView();
        }

        /// <summary>
        /// 截图view方法
        /// </summary>
        /// <returns>图片路径</returns>
        private string capVlcView()
        {
            string dir_path = Path.Combine(
                       Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "801视频快速处理");
            Directory.CreateDirectory(dir_path);

            string imgPath = Path.Combine(dir_path, $"{new Random().Next(10000)}_cap.jpg");
            ViewUtil.ExportControlView(vlcControl1, imgPath);
            toolStripStatusLabel2.Text = $"截图已放在 {imgPath}";
            return imgPath;
        }


        /// <summary>
        /// 百度OCR识别 按钮触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            textBox1.Text = "百度AI识别中...";
            string imgPath = capVlcView();

            Task.Run(() =>
            {
                string baiduOcrResult = BaiduOcrAndReturnText(imgPath);
                this.Invoke(new Action(() =>
                {
                    // 在这里更新UI控件的内容
                    textBox1.Text = baiduOcrResult;
                }));
            });
        }

        #region 百度OCR进行截图识别并返回内容
        private string BaiduOcrAndReturnText(string imgPath)
        {
           
            var image = File.ReadAllBytes(imgPath);

            var result = baidu_ocr_client.GeneralBasic(image).ToString();

            //解析对象JObject 
            JObject jo = (JObject)JsonConvert.DeserializeObject(result);
            //获取此对象key="name"和key="name_en"的值
            string res2 = jo["words_result"].ToString();
            //解析数组JArray
            JArray jArray = (JArray)JsonConvert.DeserializeObject(res2);
            //循环获取数组中的内容
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < jArray.Count; i++)
            {
                JObject jo2 = (JObject)JsonConvert.DeserializeObject(jArray[i].ToString());
                string res3 = jo2["words"].ToString();
                sb.AppendLine(res3);
            }
            return sb.ToString();
        }
        #endregion


        #region 对于时间标签的鼠标点击事件_播放与暂停

        private void label2_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                playAndPause();
            }
            if (e.Button == MouseButtons.Right)
            {
                InputDialogBox2 inputDialogBox2 = new InputDialogBox2();
                inputDialogBox2.ShowDialog();

                if (!string.IsNullOrEmpty(inputDialogBox2.res))
                {

                    //判断 
                    MediaFile mediaFile = new MediaFile(videoPath);
                    int chaiDuration = mediaFile.Video[0].duration;

                    try
                    {

                        double inputDuration = TimeSpan.Parse(inputDialogBox2.res).TotalMilliseconds;

                        if (inputDuration > chaiDuration)
                        {
                            MessageBox.Show("输入的时长不能大于视频总时长", "提示");
                            return;
                        }

                        //需要把输入的 毫秒转为 百分比 才能设置到 进度条
                        vlcControl1.VlcMediaPlayer.Position = (float)(inputDuration / chaiDuration);

                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }

        #endregion
      
        
        private void timer1_Tick(object sender, EventArgs e)
        {
            operationDuration++;
            toolStripStatusLabel2.Text = $"操作时长：{DBUtil.FormatSeconds(operationDuration)}";
        }


        #region 响应删除列表项快捷键
        private void listView1_KeyDown(object sender, KeyEventArgs e)
        {
            //使用Delete删除表项和对象
            if (Keys.Delete == e.KeyCode)
            {
                foreach (ListViewItem listViewItem in ((ListView)sender).SelectedItems)
                {
                    //首先获取索引 并删除对象，其次删除表项
                    taskList.RemoveAt(listViewItem.Index);
                    listViewItem.Remove();
                }
            }
        } 
        #endregion


        #region 添加本次的文件名留存备用
        private void button5_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                Filter = "视频文件|*.mp4", // 设置保存文件的类型，这里以.mp4为例
                Title = "保存视频文件", // 设置保存文件对话框的标题
                RestoreDirectory = true // 记住上次选择的目录
            };

            //todo 可以记住上一次的保存位置

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {

                string outPath = saveFileDialog.FileName;
                if (string.IsNullOrWhiteSpace(outPath)) { return; }

                openLastDir = new FileInfo(outPath).DirectoryName;
                lastNameStr = outPath;

                toolStripStatusLabel2.Text = $"当前对象名称： {lastNameStr}";

                button5.Enabled = false;

                CheckAndAddToTheQueue();
            }

        } 
        #endregion


        #region 查询三项是否填充，如果已经填充则 添加进列表
        private void CheckAndAddToTheQueue()
        {
            //检查空
            if (string.IsNullOrWhiteSpace(lastInTimeStr)) { return; }
            if (string.IsNullOrWhiteSpace(lastOutTimeStr)) { return; }
            if (string.IsNullOrWhiteSpace(lastNameStr)) { return; }

            //添加进队列
            TaskBean taskBean = new TaskBean(lastInTimeStr, lastOutTimeStr, lastNameStr);
            taskList.Add(taskBean);
            //添加进 列表视图
            ListViewItem item1 = new ListViewItem($"{taskBean.inTimeStr}"); // 第一列的值
            item1.SubItems.Add($"{taskBean.outTimeStr}"); // 添加其他列的值
            item1.SubItems.Add($"{new FileInfo(taskBean.name).Name}"); // 添加其他列的值
            listView1.Items.Add(item1);

            //归零
            lastInTime = 0;
            lastInTimeStr = string.Empty;
            lastOutTime = 0;
            lastOutTimeStr = string.Empty;
            lastNameStr = string.Empty;

            //解禁
            button2.Enabled = true;
            button3.Enabled = true;
            button5.Enabled = true;

        } 
        #endregion

        #region 抬起键盘时隐藏提示标签2的快进提示

        private void BatchSplittingForm_KeyUp(object sender, KeyEventArgs e)
        {
            toolStripStatusLabel2.Text = string.Empty;
        }

        #endregion

    }
}
